<!--
 * @Author: xiezhiquan3878
 * @Date: 2024-06-29 18:45:00
 * @LastEditors: zhayang 1063975710@qq.com
 * @LastEditTime: 2024-07-01 23:51:34
 * @FilePath: \heart-backed\src\views\banner\index.vue
 * @Description: 图片上传
-->
<template>
  <div class="avatar-uploader-box">
    <el-upload
      class="avatar-uploader"
      drag
      :name="'filePath'"
      :multiple="false"
      :headers="postheaders"
      :data="postData"
      action="#"
      :show-file-list="false"
      :on-success="handleAvatarSuccess"
      accept=".jpg,.jpeg,.png,.gif"
      :before-upload="beforeAvatarUpload"
      :http-request="handleUploadImg"
    >
      <div class="el-upload__text">
        <i class="el-icon-upload2"></i>
        <div>点击上传或将文件拖到此区域</div>
      </div>
    </el-upload>
    <div>
      <div
        v-for="(item, i) in list"
        :key="i"
        class="up-item"
      >
        <img
          :src="item.local"
          alt=""
          class="w-40 h-40"
          style="margin-right: 16px"
        />
        <div class="w-100% item-right">
          <div class="flex justify-between w-100%">
            <div>{{ item.name }}</div>
            <div
              class="del"
              @click="del(i)"
            >
              删除
            </div>
          </div>
          <el-progress
            class="w-100%"
            :percentage="item.progress"
            :show-text="false"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { getStsApi } from '@/api/upload'
export default {
  props: {
    url: {
      type: String,
      default: ''
    },
    // 地址是否完整
    integrityAddress: {
      type: String,
      default: '1'
    },
    upIcon: {
      type: String,
      default: 'el-icon-plus avatar-uploader-icon'
    },
    upText: {
      type: String,
      default: ''
    },
    list: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      // 图片上传
      process: '',
      imageUrl: '',
      postheaders: {
        'Auth-Token': getToken()
      },
      stsData: {},
      fileData: {},
      postData: {
        key: '',
        policy: '',
        OSSAccessKeyId: '',
        signature: '',
        'x-oss-security-token': '' // 使用STS签名时必传。
      }
    }
  },
  watch: {
    url: {
      handler(nv, oldName) {
        if (nv) {
          if (this.integrityAddress === '0') {
            if (nv.indexOf('http') !== -1) {
              this.imageUrl = nv
            } else {
              this.imageUrl = process.env.VUE_APP_FILE_API + nv
            }
          } else {
            this.imageUrl = nv
          }
        } else {
          this.imageUrl = ''
        }
      },
      immediate: true
    }
  },
  created() {
    this.setData()
  },
  methods: {
    del(i) {
      this.$emit('del', i)
    },
    generateUUID() {
      const timestamp = Date.now().toString(16)
      const random = Math.random().toString(16).slice(2)
      return `${timestamp}${random}`
    },
    setData() {
      getStsApi()
        .then((res) => {
          this.stsData = res.data
          // this.process = this.stsData.host
          // this.process = '/up-api/'
        })
        .catch(() => {})
    },
    // 截取上传文件后缀
    getSuffix(filename) {
      const pos = filename.lastIndexOf('.')
      let suffix = ''
      if (pos !== -1) suffix = filename.substring(pos)
      return suffix
    },
    handleAvatarSuccess(res, file) {
      // console.log('handleAvatarSuccess', res)
      // this.imageUrl = URL.createObjectURL(file.raw)
      this.$emit('getImg', this.imageUrl)
    },
    beforeAvatarUpload(file) {
      this.fileData = file
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isLt2M) {
        this.$message.error('上传图片大小不能超过 2MB!')
      }
      return isLt2M
    },
    handleUploadImg(file) {
      // console.log(file)
      var localUrl = null
      const that = this

      var reader = new FileReader()
      reader.onload = function (e) {
        localUrl = e.target.result
        const signature = that.stsData.mp.signature
        const ossAccessKeyId = that.stsData.body.AccessKeyId
        const policy = that.stsData.mp.policy
        const key =
          that.stsData.file_path +
          that.generateUUID() +
          '.' +
          that.getSuffix(file.file.name)
        const securityToken = that.stsData.body.SecurityToken
        const formData = new FormData()
        formData.append('name', file.file.name) // 文件名称
        formData.append('key', key) // 存储在oss的文件路径
        formData.append('OSSAccessKeyId', ossAccessKeyId) // //accessKeyId
        formData.append('policy', policy) // policy
        formData.append('Signature', signature) // 签名
        formData.append('x-oss-security-token', securityToken) // 使用STS签名时必传。
        formData.append('success_action_status', 200)
        formData.append('file', file.file, file.file.name) // 如果是base64文件，那么直接把base64字符串转成blob对象进行上传即可
        const progress = 0
        const len = that.list.length
        that.$emit('push', {
          url: '',
          name: file.file.name,
          local: localUrl,
          progress: progress
        })
        return new Promise((resolve, reject) => {
          axios
            .post(that.stsData.host, formData, {
              headers: {
                'Content-Type': 'multipart/form-data',
                'Auth-Token': getToken()
              },
              onUploadProgress: (progressEvent) => {
                const { loaded, total } = progressEvent
                that.$emit('progress', len, Math.round((loaded / total) * 100))
              }
            })
            .then((rep) => {
              // console.log('rep', rep)
              if (rep.status === 200) {
                that.imageUrl = that.stsData.host + '/' + key

                that.$emit('imgList', len, that.imageUrl)
              }
              resolve(rep)
            })
            .catch((err) => {
              reject(err)
            })
        })
      }
      reader.readAsDataURL(file.file)
    }
  }
}
</script>
<style lang="scss" scoped>
.avatar-uploader-box {
  ::v-deep {
    .avatar-uploader .el-upload {
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
    }

    .avatar-uploader .el-upload:hover {
      border-color: #04d1b8;
    }

    .avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 120px;
      height: 80px;
      line-height: 80px;
      text-align: center;
    }

    .avatar {
      width: 120px;
      height: 120px;
      display: block;
    }

    .iconfont {
      font-size: 28px;
      color: #1c1f23;
      width: 120px;
      height: 120px;
      text-align: center;
    }

    .el-upload-dragger {
      width: 100%;
      height: 100%;
      border: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      .up-show {
        margin-top: 10px;
      }

      .up-text {
        font-weight: 400;
        font-size: 10px;
        color: #6a6b6c;
        line-height: 12px;
      }
    }
  }
}
::v-deep {
  .avatar-uploader {
    .el-upload--text {
      width: 100%;
      height: 158px;
    }
  }
}
.up-item {
  background: #f4f5f9;
  border-radius: 4px 4px 4px 4px;
  padding: 12px;
  margin-top: 12px;
  display: flex;
  .del {
    font-weight: 400;
    font-size: 12px;
    color: #9e9e9e;
    cursor: pointer;
  }
  .item-right {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }
}
</style>
